package com.yykj.tencent.im.server.service.impl;

import com.alibaba.fastjson.JSON;
import com.yykj.common.enums.ResultEnums;
import com.yykj.common.exception.NormalException;
import com.yykj.common.util.PageRequestUtil;
import com.yykj.common.vo.PageData;
import com.yykj.common.vo.ResultVO;
import com.yykj.tencent.im.server.bean.callback.AfterSendGroupMsgCallback;
import com.yykj.tencent.im.server.bean.message.*;
import com.yykj.tencent.im.server.converter.GroupSuppleConverter;
import com.yykj.tencent.im.server.dto.GroupSuppleDTO;
import com.yykj.tencent.im.server.form.GroupSuppleForm;
import com.yykj.tencent.im.server.form.SelfSuppleForm;
import com.yykj.tencent.im.server.model.entity.Friend;
import com.yykj.tencent.im.server.model.entity.GroupMessage;
import com.yykj.tencent.im.server.model.entity.GroupMsgElement;
import com.yykj.tencent.im.server.model.repository.FriendRepository;
import com.yykj.tencent.im.server.model.repository.GroupMessageRepository;
import com.yykj.tencent.im.server.model.repository.GroupMsgElementRepository;
import com.yykj.tencent.im.server.service.GroupMessageService;
import com.yykj.tencent.im.server.utils.CommUtil;
import com.yykj.tencent.im.server.utils.Map2Object;
import com.yykj.tencent.im.server.utils.TimestampUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class GroupMessageServiceImpl implements GroupMessageService {

    @Value("${environment}")
    private String environment;

    private GroupMessageRepository groupMessageRepository;
    private GroupMsgElementRepository groupMsgElementRepository;
    private FriendRepository friendRepository;

    @Autowired
    public void setGroupMessageRepository(GroupMessageRepository groupMessageRepository){
        this.groupMessageRepository = groupMessageRepository;
    }
    @Autowired
    public void setGroupMsgElementRepository(GroupMsgElementRepository groupMsgElementRepository){
        this.groupMsgElementRepository = groupMsgElementRepository;
    }
    @Autowired
    public void setFriendRepository(FriendRepository friendRepository){
        this.friendRepository = friendRepository;
    }



    /**
     * 群内发言之后回调
     */
    @Async
    @Override
    public void addGroupMessage(Map<String, Object> map) {
        // map->AfterSendGroupMsgCallback
        AfterSendGroupMsgCallback msg = (AfterSendGroupMsgCallback) Map2Object.mapToObject(map,AfterSendGroupMsgCallback.class);
        // AfterSendGroupMsgCallback --> GroupMessage
        GroupMessage groupMessage = new GroupMessage();
        BeanUtils.copyProperties(msg,groupMessage);
        groupMessage.setMsgTime(TimestampUtil.ofEpochSecond(msg.getMsgTime()));
        groupMessage.setMsgBody(JSON.toJSONString(msg.getMsgBody()));
        groupMessage.setEnvironment(environment);
        groupMessage.setName(msg.getCloudCustomData());
        groupMessageRepository.save(groupMessage);

        //更新账号与群组交互
        Friend friend = friendRepository.findByFromAccountAndToAccount(msg.getFromAccount(),msg.getGroupId());
        if(friend == null){
            friend = new Friend();
            friend.setEnvironment(environment);
            friend.setFromAccount(msg.getFromAccount());
            friend.setToAccount(msg.getGroupId());
            friend.setNumber(1);
            friend.setType("G");
            friend.setUpdateTime(LocalDateTime.now());
        }else{
            friend.setUpdateTime(LocalDateTime.now());
            friend.setNumber(friend.getNumber()+1);
        }
        friendRepository.save(friend);

        //消息内容保存
        List<GroupMsgElement> mList = new ArrayList<>();
        for(TIMMsgElement element:msg.getMsgBody()){
            if(element.getMsgType().equals("TIMTextElem"))
                continue;
            GroupMsgElement ge = new GroupMsgElement();
            //补充资料名称
            ge.setName(groupMessage.getName());
            ge.setEnvironment(environment);
            ge.setGroupId(groupMessage.getGroupId());
            ge.setEleTime(groupMessage.getMsgTime());

            switch (element.getMsgType()){
                //音频
                case "TIMSoundMsgElement":
                    TIMSoundMsgElement.SoundMsgContent sound = ((TIMSoundMsgElement)element).getMsgContent();
                    ge.setType("Sound");
                    ge.setUuid(sound.getUuid());
                    ge.setUrl(sound.getUrl());
                    ge.setSize(CommUtil.byte2KMG(sound.getSize()));
                    break;
                //视频
                case "TIMVideoFileMsgElement":
                    TIMVideoFileMsgElement.VideoFileMsgContent video = ((TIMVideoFileMsgElement)element).getMsgContent();
                    ge.setType("Video");
                    ge.setUrl(video.getVideoUrl());
                    ge.setAbbrImageUrl(video.getThumbUrl());
                    ge.setUuid(video.getVideoUuid());
                    ge.setSize(CommUtil.byte2KMG(video.getVideoSize()));
                    break;
                //图片
                case "TIMImageMsgElement":
                    TIMImageMsgElement.ImageMsgContent image = ((TIMImageMsgElement)element).getMsgContent();
                    ge.setType("Image");
                    List<TIMImageMsgElement.ImageInfo> images = image.getImageInfoArray();
                    ge.setUrl(images.get(0).getUrl());
                    ge.setBigImageUrl(images.get(1).getUrl());
                    ge.setAbbrImageUrl(images.get(2).getUrl());
                    ge.setUuid(image.getUuid());
                    ge.setSize(CommUtil.byte2KMG(images.get(0).getSize()));
                    break;
                //文件
                case "TIMFileMsgElement":
                    TIMFileMsgElement.FileMsgContent file = ((TIMFileMsgElement)element).getMsgContent();
                    ge.setType("File");
                    ge.setUrl(file.getUrl());
                    ge.setUuid(file.getUuid());
                    ge.setSize(CommUtil.byte2KMG(file.getFileSize()));
                    break;
                //自定义消息
                case "TIMCustomElem":
                    TIMCustomMsgElement.CustomMsgContent custom = ((TIMCustomMsgElement)element).getMsgContent();
                    ge.setType("Custom");
                    ge.setData(custom.getData());
                    ge.setTitle(custom.getDesc());
                    break;
            }
            mList.add(ge);
        }
        groupMsgElementRepository.saveAll(mList);
    }


    /**
     * 在线会诊--补充资料
     */
    @Override
    public PageData<GroupSuppleDTO> listGroupSupple(GroupSuppleForm groupSuppleForm) {
        groupSuppleForm.setEnv(environment);
        if (groupSuppleForm.getGroupId() == null ) {
            throw new NormalException(ResultEnums.PARAM_ERROR);
        }
        Pageable page = PageRequest.of(PageRequestUtil.getPage(groupSuppleForm.getCurrentPage())
                ,PageRequestUtil.getSize(groupSuppleForm.getPageSize())
                , Sort.by(Sort.Direction.DESC, "eleTime"));
        Page<GroupMsgElement> list = groupMsgElementRepository.findAll(new Specification<GroupMsgElement>(){
            @Override
            public Predicate toPredicate(Root<GroupMsgElement> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
                List<Predicate> predicateList = new ArrayList<>();
                predicateList.add(builder.equal(root.get("groupId"),groupSuppleForm.getGroupId()));
                if(!groupSuppleForm.getType().isEmpty()){
                    predicateList.add(builder.equal(root.get("type"),groupSuppleForm.getType()));
                }
                predicateList.add(builder.equal(root.get("environment"),groupSuppleForm.getEnv()));
                Predicate[] predicates = new Predicate[predicateList.size()];
                return query.where(predicateList.toArray(predicates)).getRestriction();
            }
        },page);

        PageData<GroupSuppleDTO> result = new PageData<GroupSuppleDTO>();
        PageData<GroupMsgElement> pageData = PageData.formatList(list, groupSuppleForm.getCurrentPage(), groupSuppleForm.getPageSize());
        BeanUtils.copyProperties(pageData,result);
        result.setList(GroupSuppleConverter.convert(list.getContent()));
        return result;
    }

    /**
     * 自定义补充资料
     */
    @Override
    public ResultVO<GroupSuppleDTO> uploadSelfSupple(SelfSuppleForm form) {
        //SelfSuppleForm --> GroupMsgElement
        GroupMsgElement groupMessage = new GroupMsgElement();
        BeanUtils.copyProperties(form,groupMessage);
        groupMessage.setEleTime(LocalDateTime.now());
        groupMessage.setEnvironment(environment);
        groupMessage.setAbbrImageUrl(form.getCoverImage());
        GroupMsgElement ge = groupMsgElementRepository.save(groupMessage);
        GroupSuppleDTO groupSuppleDTO = new GroupSuppleDTO();
        BeanUtils.copyProperties(ge,groupSuppleDTO);
        return ResultVO.success(groupSuppleDTO);
    }


}
